using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Asp.Versioning.ApiExplorer;

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using OpenIddict.Validation.AspNetCore;

using Swashbuckle.AspNetCore.SwaggerUI;

using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;

namespace WL.Think.Abp.Extensions
{
    public static class ApplicationBuilderExtensions
    {
        /// <summary>
        /// 配置并使用异常处理中间件
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseException(this IApplicationBuilder app)
        {
            var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                return app;
            }
            app.UseErrorPage();
            app.UseHsts();
            return app;
        }

        /// <summary>
        /// 使用多租户中间件
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseMultiTenant(this IApplicationBuilder app)
        {
            var configuration = app.ApplicationServices.GetRequiredService<IConfiguration>();
            var enableMultiTenancy = configuration.GetValue("App:MultiTenancy", false);
            if (enableMultiTenancy)
            {
                app.UseMiddleware<MultiTenancyMiddleware>();
            }
            return app;
        }


        /// <summary>
        /// 使用 Swagger 和 SwaggerUI 中间件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseSwaggerAndUI(this IApplicationBuilder app, Action<SwaggerUIOptions>? action = null)
        {
            app.UseSwagger();
            app.UseAbpSwaggerUI(options =>
            {
                var configuration = app.ApplicationServices.GetRequiredService<IConfiguration>();
                options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);

                var provider = app.ApplicationServices.GetRequiredService<IApiVersionDescriptionProvider>();
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                }
                action?.Invoke(options);
            });

            return app;
        }

        /// <summary>
        /// 使用OpenIddit中间件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="schema"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseOpenIddictValidation(this IApplicationBuilder app, string schema = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)
        {
            return app.Use(async (ctx, next) =>
            {
                if (ctx.User.Identity?.IsAuthenticated != true)
                {
                    var result = await ctx.AuthenticateAsync(schema);
                    if (result.Succeeded && result.Principal != null)
                    {
                        ctx.User = result.Principal;
                    }
                }

                await next();
            });
        }
    }
}
